{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "32ab3437-5abd-4e66-a3c5-73b969702834",
   "metadata": {},
   "source": [
    "# 7. 人工神经网络基础\n",
    "\n",
    "- 感知器\n",
    "- 交叉熵损失计算函数\n",
    "- 单层神经网络\n",
    "- 多层神经网络\n",
    "- ReLU函数\n",
    "- 误差反向传播算法"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d1f20875-c50d-46df-906b-49ec1d0c6002",
   "metadata": {},
   "source": [
    "## 7.1 感知器算法实现案例"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "c90a18b9-d8e8-431c-856c-35f1e4ed05e1",
   "metadata": {},
   "source": [
    "### 1.任务描述\n",
    "\n",
    "假设有4个样本，每个样本有2个特征。已知4个样本的特征为[0, 0], [0, 1], [1, 0], [1, 1]，4个样本对应的标签为-1, -1, -1, 1。\n",
    "\n",
    "\n",
    "要求：\n",
    "- 以样本的第一个特征为x轴，以样本的第二个特征为y轴，绘制4个样本的散点图，标签为1的样本绘制成红色星号（*），标签为-1的样本绘制成绿色加号（+）。观察散点图，确定样本是线性可分的。\n",
    "- 使用感知器算法，找出一个向量W和一个常数b，使得其对于4个样本有：\n",
    "  - 若$y_i = +1$，则$W^TX_i+b>0$\n",
    "  - 若$y_i = -1$，则$W^TX_i+b<0$\n",
    "\n",
    "    其中，$y_i$是第i个样本的标签，$X_i$是第i个样本的特征向量。\n",
    "    \n",
    "- 绘制初始的决策边界（红色实线）和最终的决策边界（绿色虚线）"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "f5b4fc39-cbcf-432a-bf1e-e75e642d4b87",
   "metadata": {},
   "source": [
    "### 2.知识准备\n",
    "\n",
    "见教程。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b624ebee-980f-4c1e-b963-a24ff0b669f6",
   "metadata": {},
   "source": [
    "### 3.任务分析\n",
    "\n",
    "在训练过程中，可以使用分支结构来指定在不同情况下权值和偏移值的更新方式。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "435c6090-cfda-4f46-a550-22a368e41e4a",
   "metadata": {},
   "source": [
    "### 4.任务实施\n"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "ec75eb6c-5da3-467d-a471-ca3b47242dd6",
   "metadata": {},
   "source": [
    "执行代码"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "2ae9da58-e339-4d22-9f8d-ca255711d89e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "参数更新次数： 11\n",
      "更新后的W： [2.49589878 0.95454587]\n",
      "更新后的b： -2.856528370296921\n"
     ]
    },
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 600x400 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "# 1,样本数据\n",
    "# 特征\n",
    "X = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])\n",
    "# 标签\n",
    "y = np.array([-1, -1, -1, 1])\n",
    "# 2,绘制样本特征数据散点图，如果对应标签是-1，绘成绿色加号（+），如果对应标签为1，绘成红色星号（*）\n",
    "fig=plt.figure(figsize=(6,4))\n",
    "# 设置x轴数值显示范围\n",
    "plt.xlim(-4,4)\n",
    "# 设置y轴数值显示范围\n",
    "plt.ylim(-4,4)\n",
    "# 绘制\n",
    "for index,item in enumerate(X):\n",
    "    if y[index]==1:\n",
    "        plt.scatter(item[0],item[1],c='r',marker='*')\n",
    "    elif y[index]==-1:\n",
    "        plt.scatter(item[0],item[1],c='g',marker='+')\n",
    "\n",
    "# 3,初始化参数\n",
    "# 学习率\n",
    "lr=1\n",
    "np.random.seed(612)\n",
    "# 偏置\n",
    "b=np.random.rand(1)[0]\n",
    "# 权值矩阵\n",
    "W=np.random.rand(2)\n",
    "\n",
    "# print(W,b)\n",
    "# 4，绘制初始直线（实线）W[0]*x1 + W[1]*x2 + b=0\n",
    "# 生成x1轴数据\n",
    "X1=np.linspace(-5,5,11)\n",
    "# 计算x2轴数据\n",
    "X2 = -(W[0]*X1 + b) / W[1]\n",
    "plt.plot(X1,X2,'r-')\n",
    "# 更新次数\n",
    "updateNum=0\n",
    "# 5,寻找决策边界\n",
    "for epochs in range(5):\n",
    "    for index,item in enumerate(X):\n",
    "        # 计算预测值\n",
    "        result=W[0]*item[0]+W[1]*item[1]+b\n",
    "        # 如果预测值大于0，但对应的标签等于-1\n",
    "        if result>0 and y[index]==-1:\n",
    "            W[0] = W[0]-item[0]*lr\n",
    "            W[1] = W[1]-item[1]*lr\n",
    "            b = b-1*lr\n",
    "            updateNum+=1\n",
    "        # 如果预测值小于0，但对应的标签等于1\n",
    "        elif result<0 and y[index]==1:\n",
    "            W[0] = W[0]+item[0]*lr\n",
    "            W[1] = W[1]+item[1]*lr\n",
    "            b = b+1*lr\n",
    "            updateNum+=1\n",
    "\n",
    "print('参数更新次数：',updateNum)\n",
    "print('更新后的W：',W)\n",
    "print('更新后的b：',b)\n",
    "            \n",
    "# 绘制更新后的直线（虚线）\n",
    "X2 = -(W[0]*X1 + b) / W[1]\n",
    "plt.plot(X1,X2,'g--')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e3b3e36e-8418-4caf-af51-d8ac80e2a321",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
